#include "p30f6010A.h"
#include "interfaceOptions.h"

#ifndef INTERFACE_DEFINES_H
#define INTERFACE_DEFINES_H

typedef char boolean;
#define true	1
#define false	0

typedef enum
{
	OS_PASSTHROUGH 	= 1,
	OS_RX_OK	 	= 2,
	OS_CTRL_COMM_OK	= 4
}OP_STATES;

typedef struct
{
	unsigned passthrough 	:1;		// In passthrough mode
	unsigned mode_ok		:1;		// Mode connected ok
	unsigned failsafe_ok	:1;		// Failsafe connected ok
	unsigned rx_ok			:1;		// Receiver connected ok
	unsigned cntrl_comm_ok	:1;		// Control communication ok (servo control)
	unsigned frame_ok		:1;		// Complete servo frame received ok
	unsigned 				:11;	// Not defined yet
} OP_STATE;

extern OP_STATE op_status;

// Max inputs and outputs
#define MAX_INPUTS	8
#define MAX_OUTPUTS	8


void gps_startup_sequence(int gpscount) ;
boolean gps_nav_valid(void) ;

//void init_clock(void) ;
//void init_T3(void) ;
void init_pwm(void) ;
void init_cntrl_comms(void);
void init_canbus_comms(void);
//void init_capture(void) ;
//void init_USART1(void) ;
void init_heartbeat(void);

void init_states(void);

//void state_machine(void) ;
//void filterInputs(void) ;

extern boolean needSaveExtendedState ;
extern boolean timer_5_on ;

extern int defaultCorcon ;

extern unsigned int uiServosFound;	// Record of which servos have been found
extern boolean		frameComplete;	// Flag for frame complete

void send_servo_data(void);			// Interface send data to autopilot
void receive_servo_data(void);		// Interface receive data from autopilot

void send_servo_outputs(void);		// Autopilot send servo data to interface
void receive_servo_inputs(void);	// Autopilot recieve servo data from interface

// Servo data buffers for interface
extern unsigned int ServoOutDataBuff[8];
extern unsigned int ServoInDataBuff[8];

extern unsigned int RxTimeouts;

int pulsesat(long) ;

extern unsigned int rise[MAX_INPUTS+1] ;	// rising edge clock capture for radio inputs

extern int pwIn[MAX_INPUTS+1] ;	// pulse widths of radio inputs
extern int pwOut[MAX_OUTPUTS+1] ;	// pulse widths for servo outputs


// Empirical results show that reading and writing to the
// "Timer On" function loses clock cycles in the timer. 
// So the software makes a test using a parallel variable
// called timer_5_on.
#define indicate_loading_inter		if ( timer_5_on == 0 )	\
									{						\
										T5CONbits.TON = 1 ;	\
										timer_5_on = 1 ;	\
									}

#define indicate_loading_main		if ( timer_5_on == 1 )	\
									{						\
										T5CONbits.TON = 0 ;	\
										timer_5_on = 0 ;	\
									}


// When ISRs fire during dsp math calls, state is not preserved properly, so we
// have to help preserve extra register state on entry and exit from ISRs.
// In addition, the dsp math calls change and restore CORCON internally, so
// if we fire an ISR in the middle of a dsp math call, CORCON can be set to
// an unexpected value, so we also restore CORCON to the application default,
// which we save in main().  We keep track of whether or not we're running dsp
// calls in needSaveExtendedState var, and only perform these actions if so.
#define interrupt_save_extended_state \
	{ \
		if (needSaveExtendedState) { \
			__asm__("push CORCON"); \
			__asm__("push SR"); \
			__asm__("push MODCON"); \
			__asm__("push XBREV"); \
			__asm__("push ACCAL"); \
			__asm__("push ACCAH"); \
			__asm__("push ACCAU"); \
			__asm__("push ACCBL"); \
			__asm__("push ACCBH"); \
			__asm__("push ACCBU"); \
			__asm__("push RCOUNT"); \
			__asm__("push DCOUNT"); \
			__asm__("push DOSTARTL"); \
			__asm__("push DOSTARTH"); \
			__asm__("push DOENDL"); \
			__asm__("push DOENDH"); \
			int asmDoRestoreExtendedState = 1; \
			__asm__("push %0" : "+r"(asmDoRestoreExtendedState)); \
			CORCON = defaultCorcon; \
			needSaveExtendedState = 0; \
		} \
		else \
		{ \
			int asmDoRestoreExtendedState = 0; \
			__asm__("push %0" : "+r"(asmDoRestoreExtendedState)); \
		} \
	}

#define interrupt_restore_extended_state \
	{ \
		int asmDoRestoreExtendedState; \
		__asm__("pop %0" : "+r"(asmDoRestoreExtendedState)); \
		if (asmDoRestoreExtendedState) { \
			__asm__("pop DOENDH"); \
			__asm__("pop DOENDL"); \
			__asm__("pop DOSTARTH"); \
			__asm__("pop DOSTARTL"); \
			__asm__("pop DCOUNT"); \
			__asm__("pop RCOUNT"); \
			__asm__("pop ACCBU"); \
			__asm__("pop ACCBH"); \
			__asm__("pop ACCBL"); \
			__asm__("pop ACCAU"); \
			__asm__("pop ACCAH"); \
			__asm__("pop ACCAL"); \
			__asm__("pop XBREV"); \
			__asm__("pop MODCON"); \
			__asm__("pop SR"); \
			__asm__("pop CORCON"); \
			needSaveExtendedState = 1; \
		} \
	}


// Channel numbers on the board, mapped to positions in the pulse width arrays.
#define CHANNEL_UNUSED	0	// pwIn[0], pwOut[0], etc. are not used, but allow lazy code everywhere else  :)
#define CHANNEL_1		1
#define CHANNEL_2		2
#define CHANNEL_3		3
#define CHANNEL_4		4
#define CHANNEL_5		5
#define CHANNEL_6		6
#define CHANNEL_7		7
#define CHANNEL_8		8

#define SERVORANGE (int) SERVOSAT*1000
#define SERVOMAX 3000 + SERVORANGE
#define SERVOMIN 3000 - SERVORANGE

#define tmr1_period 0x2000 // sets time period for timer 1 interrupt to 0.5 seconds
//#define FILTERSHIFT 6 // filter shift divide


#endif


/****************************************************************************/
// This is part of the servo and radio interface software
//
// ServoInterface source code
//	http://code.google.com/p/rc-servo-interface
//
// Copyright 2010 ServoInterface Team
// See the AUTHORS.TXT file for a list of authors of ServoInterface.
//
// ServoInterface is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ServoInterface is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License 
// along with ServoInterface.  If not, see <http://www.gnu.org/licenses/>.
//
// Many parts of ServoInterface use either modified or unmodified code
// from the MatrixPilot pilot project.
// The project also contains code for modifying MatrixPilot to operate
// with ServoInterface.
// For details, credits and licenses of MatrixPilot see the AUTHORS.TXT file.
// or see this website: http://code.google.com/p/gentlenav
/****************************************************************************/
